home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / utilities / itrack.lha / intuitrack.c next >
Encoding:
C/C++ Source or Header  |  1994-05-17  |  11.3 KB  |  432 lines

  1. /**
  2.  **   IntuiTrack V1.0
  3.  **
  4.  **   (c)1994 by Matthias Meixner
  5.  */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <exec/exec.h>
  10. #include <proto/exec.h>
  11. #include <exec/execbase.h>
  12. #include <dos.h>
  13. #include <stdlib.h>
  14.  
  15. #include <clib/alib_protos.h>
  16.  
  17. extern struct ExecBase *SysBase;
  18. extern struct IntuitionBase *IntuitionBase;
  19.  
  20. long WatchSig;
  21.  
  22. struct Task *WatchTask;
  23.  
  24. void *MemPool;
  25.  
  26. #define BUFS 64
  27.  
  28. char buffer[BUFS][128];
  29. int read,write;
  30.  
  31. #define TYPE_WINDOW     0
  32. #define TYPE_SCREEN     1
  33. #define TYPE_SCREENLOCK 2
  34.  
  35. struct ResBlock {
  36.    struct ResBlock *Next;
  37.    int    Type;
  38.    void *Res;
  39.    void *Base;
  40. };
  41.  
  42. #define MAX_TASKS 100
  43.  
  44. void *tasklist[MAX_TASKS];
  45. struct ResBlock *reslist[MAX_TASKS];
  46. int taskcnt=0;
  47.  
  48.  
  49. void addWatch(void *tsk)
  50. {
  51.    Forbid();
  52.    if(taskcnt<MAX_TASKS-1) {
  53.       tasklist[taskcnt]=tsk;
  54.       reslist[taskcnt++]=NULL;
  55.    }
  56.    Permit();
  57. }
  58. void delWatch(void *tsk)
  59. {
  60.    int a;
  61.  
  62.    Forbid();
  63.  
  64.    for(a=0;a<taskcnt;a++) {
  65.       if(tasklist[a]==tsk) {
  66.          while(a<taskcnt-1) {
  67.             tasklist[a]=tasklist[a+1];
  68.             reslist[a]=reslist[a+1];
  69.             a++;
  70.          }
  71.          break;
  72.       }
  73.    }
  74.  
  75.    Permit();
  76. }
  77. int findWatch(void *tsk)
  78. {
  79.    int a;
  80.    int found=-1;
  81.  
  82.    Forbid();
  83.    for(a=0;a<taskcnt;a++) {
  84.       if(tasklist[a]==tsk) {
  85.          found=a;
  86.          break;
  87.       }
  88.    }
  89.    Permit();
  90.    return(found);
  91. }
  92.  
  93. char *TypeStr[]={"Window","Screen","Screenlock"};
  94.  
  95. void MyAddResource(int Type,void *adr,void *base);
  96. void MyRemResource(void *adr);
  97. void MyFlushResource(void);
  98.  
  99. /* Intuition-patches */
  100.  
  101. void __asm *(*OldOpenScreen)( register __a0 void *ns,
  102.                                        register __a6 void *base);
  103.  
  104. void __interrupt __saveds __asm *NewOpenScreen(register __a0 void *ns,
  105.                                                   register __a6 void *base)
  106. {
  107.    void *scr;
  108.  
  109.    scr=OldOpenScreen(ns,base);
  110.  
  111.    if(scr) MyAddResource(TYPE_SCREEN,scr,base);
  112.  
  113.    return(scr);
  114. }
  115. void __asm *(*OldOpenWindow)( register __a0 void *nw,
  116.                                        register __a6 void *base);
  117.  
  118. void __interrupt __saveds __asm *NewOpenWindow(register __a0 void *nw,
  119.                                                   register __a6 void *base)
  120. {
  121.    void *win;
  122.  
  123.    win=OldOpenWindow(nw,base);
  124.  
  125.    if(win) MyAddResource(TYPE_WINDOW,win,base);
  126.  
  127.    return(win);
  128. }
  129.  
  130. void __asm *(*OldOpenScreenTagList)( register __a0 void *ns,
  131.                                      register __a1 void *tags,
  132.                                      register __a6 void *base);
  133.  
  134. void __interrupt __saveds __asm *NewOpenScreenTagList(register __a0 void *ns,
  135.                                                   register __a1 void *tags,
  136.                                                   register __a6 void *base)
  137. {
  138.    void *scr;
  139.  
  140.    scr=OldOpenScreenTagList(ns,tags,base);
  141.  
  142.    if(scr) MyAddResource(TYPE_SCREEN,scr,base);
  143.  
  144.    return(scr);
  145. }
  146. void __asm *(*OldOpenWindowTagList)( register __a0 void *nw,
  147.                                      register __a1 void *tags,
  148.                                      register __a6 void *base);
  149.  
  150. void __interrupt __saveds __asm *NewOpenWindowTagList(register __a0 void *nw,
  151.                                                   register __a1 void *tags,
  152.                                                   register __a6 void *base)
  153. {
  154.    void *win;
  155.  
  156.    win=OldOpenWindowTagList(nw,tags,base);
  157.  
  158.    if(win) MyAddResource(TYPE_WINDOW,win,base);
  159.  
  160.    return(win);
  161. }
  162.  
  163. BOOL __asm (*OldCloseScreen)( register __a0 void *ns,
  164.                              register __a6 void *base);
  165.  
  166. BOOL __interrupt __saveds __asm NewCloseScreen(register __a0 void *ns,
  167.                                                register __a6 void *base)
  168. {
  169.    if(ns) MyRemResource(ns);
  170.  
  171.    return(OldCloseScreen(ns,base));
  172. }
  173. void __asm *(*OldCloseWindow)( register __a0 void *nw,
  174.                                register __a6 void *base);
  175.  
  176. void __interrupt __saveds __asm NewCloseWindow(register __a0 void *nw,
  177.                                                register __a6 void *base)
  178. {
  179.    if(nw) MyRemResource(nw);
  180.  
  181.    OldCloseWindow(nw,base);
  182. }
  183.  
  184. void __asm *(*OldLockScreen)( register __a0 void *ns,
  185.                                        register __a6 void *base);
  186.  
  187. void __interrupt __saveds __asm *NewLockScreen(register __a0 void *ns,
  188.                                                   register __a6 void *base)
  189. {
  190.    void *scr;
  191.  
  192.    scr=OldLockScreen(ns,base);
  193.  
  194.    if(scr) MyAddResource(TYPE_SCREENLOCK,scr,base);
  195.  
  196.    return(scr);
  197. }
  198. void __asm (*OldUnlockScreen)( register __a0 void *ns,
  199.                               register __a1 void *ns2,
  200.                              register __a6 void *base);
  201.  
  202. void __interrupt __saveds __asm NewUnlockScreen(register __a0 void *ns,
  203.                                                register __a1 void *ns2,
  204.                                                register __a6 void *base)
  205. {
  206.    void *res;
  207.    if(ns) {
  208.       res=OldLockScreen(ns,base);
  209.       OldUnlockScreen(NULL,res,base);
  210.       if(res) MyRemResource(res);
  211.    } else {
  212.       if(ns2) MyRemResource(ns2);
  213.    }
  214.    OldUnlockScreen(ns,ns2,base);
  215. }
  216.  
  217. /* Exec-patches */
  218.  
  219. APTR __asm (*OldAddTask)(register __a1 struct Task *,
  220.                         register __a2 APTR ,
  221.                         register __a3 APTR , register __a6 Base);
  222.  
  223. APTR __interrupt __saveds __asm NewAddTask(register __a1 struct Task * tsk,
  224.                         register __a2 APTR lpc,
  225.                         register __a3 APTR fpc, register __a6 Base)
  226. {
  227.    Forbid();
  228.    sprintf(buffer[write],"Task captured : %s 0x%08lx",tsk->tc_Node.ln_Name,tsk);
  229.    write++;
  230.    write&=BUFS-1;
  231.    Permit();
  232.    addWatch(tsk);
  233.    Signal(WatchTask,1<<WatchSig);
  234.    return(OldAddTask(tsk,lpc,fpc,Base));
  235. }
  236. void __asm (*OldRemTask)(register __a1 struct Task *, register __a6 Base);
  237.  
  238. void __interrupt __saveds __asm NewRemTask(register __a1 struct Task *tsk,
  239.                                        register __a6 Base)
  240. {
  241.    struct Task *rtask;
  242.    rtask=tsk?tsk:FindTask(0);
  243.  
  244.    MyFlushResource();
  245.  
  246.    if(findWatch(rtask)>=0) {
  247.  
  248.       Forbid();
  249.       sprintf(buffer[write],"Task released : %s 0x%08lx",rtask->tc_Node.ln_Name,rtask);
  250.  
  251.       write++;
  252.       write&=BUFS-1;
  253.       Permit();
  254.  
  255.       delWatch(rtask);
  256.       Signal(WatchTask,1<<WatchSig);
  257.    }
  258.    OldRemTask(tsk,Base);
  259. }
  260.  
  261. /* Management functions */
  262.  
  263. void MyAddResource(int Type,void *adr,void *base)
  264. {
  265.    int tnum;
  266.    struct Task *task=FindTask(0);
  267.    struct ResBlock *res;
  268.  
  269.    if(res=LibAllocPooled(MemPool,sizeof(struct ResBlock))) {
  270.  
  271.       res->Type=Type;
  272.       res->Res=adr;
  273.       res->Base=base;
  274.  
  275.       if((tnum=findWatch(task))>=0) {
  276.          res->Next=reslist[tnum];
  277.          reslist[tnum]=res;
  278.       }
  279.    }
  280.  
  281. /*   Forbid();
  282.    sprintf(buffer[write],"%s: AddResource %s  0x%08x",task->tc_Node.ln_Name,
  283.                          TypeStr[Type],adr);
  284.    write++;
  285.    write&=BUFS-1;
  286.    Permit();
  287.    Signal(WatchTask,1<<WatchSig); */
  288. }
  289. void MyRemResource(void *adr)
  290. {
  291.    int tnum;
  292.    struct Task *task=FindTask(0);
  293.  
  294.    if((tnum=findWatch(task))>=0) {
  295.       struct ResBlock *res,*mem=NULL;
  296.  
  297.       if(!(res=reslist[tnum])) return;
  298.  
  299.       if(reslist[tnum]->Res==adr) {
  300.          mem=reslist[tnum];
  301.          reslist[tnum]=reslist[tnum]->Next;
  302.       } else {
  303.          while(res->Next) {
  304.             if(res->Next->Res==adr) {
  305.                mem=res->Next;
  306.                res->Next=res->Next->Next;
  307.                break;
  308.             }
  309.             res=res->Next;
  310.          }
  311.       }
  312.  
  313.       if(mem) LibFreePooled(MemPool,mem,sizeof(struct ResBlock));
  314.    }
  315. }
  316. void MyFlushResource(void)
  317. {
  318.    int tnum;
  319.    struct Task *task=FindTask(0);
  320.  
  321.    if((tnum=findWatch(task))>=0) {
  322.  
  323.       struct ResBlock *res;
  324.  
  325.       while(res=reslist[tnum]) {
  326.          reslist[tnum]=res->Next;
  327.  
  328.          switch(res->Type) {
  329.             case TYPE_WINDOW: OldCloseWindow(res->Res,res->Base);
  330.                               break;
  331.             case TYPE_SCREEN: OldCloseScreen(res->Res,res->Base);
  332.                               break;
  333.             case TYPE_SCREENLOCK:
  334.                               OldUnlockScreen(NULL,res->Res,res->Base);
  335.                               break;
  336.          }
  337.          Forbid();
  338.          sprintf(buffer[write],"\033[33mUnfreed %s\033[0m Task: \033[32m%s\033[0m",
  339.                                TypeStr[res->Type],task->tc_Node.ln_Name);
  340.          write++;
  341.          write&=BUFS-1;
  342.          Permit();
  343.          Signal(WatchTask,1<<WatchSig);
  344.          LibFreePooled(MemPool,res,sizeof(struct ResBlock));
  345.       }
  346.  
  347.       reslist[tnum]=NULL;
  348.    }
  349. }
  350.  
  351. /* Safe removing of patches */
  352.  
  353. void ResetFunction(struct Library *lib,LONG offset,APTR function,APTR oldfunction)
  354. {
  355.    ULONG *func=(ULONG *)(((ULONG)lib)+offset+2);
  356.  
  357.    Forbid();
  358.  
  359.    while(*func!=(ULONG)function) {
  360.       Permit();
  361.       puts("could not remove patches ( ^C: retry )");
  362.       Wait(SIGBREAKF_CTRL_C);
  363.       puts("retrying ...");
  364.       Forbid();
  365.    }
  366.  
  367.    SetFunction(lib,offset,oldfunction);
  368.    Permit();
  369. }
  370.  
  371. main()
  372. {
  373.    long mask;
  374.  
  375.    if(!(MemPool=LibCreatePool(MEMF_PUBLIC,1024,128))) {
  376.       fprintf(stderr,"Could not allocate memorypool\n");
  377.       exit(EXIT_FAILURE);
  378.    }
  379.  
  380.    WatchSig=AllocSignal(-1);
  381.    WatchTask=FindTask(0);
  382.  
  383.    puts("IntuiTrack V1.0 ©1994 by Matthias Meixner");
  384.  
  385.    /* Exec-patches */
  386.    OldAddTask=SetFunction((void *)SysBase,-282,(ULONG (*)()) NewAddTask);
  387.    OldRemTask=SetFunction((void *)SysBase,-288,(ULONG (*)()) NewRemTask);
  388.  
  389.    /* Intuition-patches */
  390.    OldOpenWindow=SetFunction((void *)IntuitionBase,-0xcc,(ULONG (*)()) NewOpenWindow);
  391.    OldOpenScreen=SetFunction((void *)IntuitionBase,-0xc6,(ULONG (*)()) NewOpenScreen);
  392.    OldOpenWindowTagList=SetFunction((void *)IntuitionBase,-0x25e,(ULONG (*)()) NewOpenWindowTagList);
  393.    OldOpenScreenTagList=SetFunction((void *)IntuitionBase,-0x264,(ULONG (*)()) NewOpenScreenTagList);
  394.    OldCloseWindow=SetFunction((void *)IntuitionBase,-0x48,(ULONG (*)()) NewCloseWindow);
  395.    OldCloseScreen=SetFunction((void *)IntuitionBase,-0x42,(ULONG (*)()) NewCloseScreen);
  396.    OldLockScreen=SetFunction((void *)IntuitionBase,-0x1fe,(ULONG (*)()) NewLockScreen);
  397.    OldUnlockScreen=SetFunction((void *)IntuitionBase,-0x204,(ULONG (*)()) NewUnlockScreen);
  398.  
  399.    while(1) {
  400.       mask=Wait((1<<WatchSig) | SIGBREAKF_CTRL_C);
  401.       if(mask & ~SIGBREAKF_CTRL_C) {
  402.          while(read!=write) {
  403.             puts(buffer[read]);
  404.             read++;
  405.             read &=(BUFS-1);
  406.          }
  407.       }
  408.       if(mask & SIGBREAKF_CTRL_C) break;
  409.    }
  410.  
  411.    /* Exec-patches */
  412.    ResetFunction((struct Library *)SysBase,-282,(ULONG (*)()) NewAddTask,(ULONG (*)()) OldAddTask);
  413.    ResetFunction((struct Library *)SysBase,-288,(ULONG (*)()) NewRemTask,(ULONG (*)()) OldRemTask);
  414.  
  415.    /* Intuition-patches */
  416.    ResetFunction((void *)IntuitionBase,-0xcc,(ULONG (*)()) NewOpenWindow,(ULONG (*)()) OldOpenWindow);
  417.    ResetFunction((void *)IntuitionBase,-0xc6,(ULONG (*)()) NewOpenScreen,(ULONG (*)()) OldOpenScreen);
  418.    ResetFunction((void *)IntuitionBase,-0x25e,(ULONG (*)()) NewOpenWindowTagList,(ULONG (*)()) OldOpenWindowTagList);
  419.    ResetFunction((void *)IntuitionBase,-0x264,(ULONG (*)()) NewOpenScreenTagList,(ULONG (*)()) OldOpenScreenTagList);
  420.    ResetFunction((void *)IntuitionBase,-0x48,(ULONG (*)()) NewCloseWindow,(ULONG (*)()) OldCloseWindow);
  421.    ResetFunction((void *)IntuitionBase,-0x42,(ULONG (*)()) NewCloseScreen,(ULONG (*)()) OldCloseScreen);
  422.    ResetFunction((void *)IntuitionBase,-0x1fe,(ULONG (*)()) NewLockScreen,(ULONG (*)()) OldLockScreen);
  423.    ResetFunction((void *)IntuitionBase,-0x204,(ULONG (*)()) NewUnlockScreen,(ULONG (*)()) OldUnlockScreen);
  424.  
  425.    FreeSignal(WatchSig);
  426.    puts("All patches removed.");
  427.    LibDeletePool(MemPool);
  428. }
  429.  
  430.  
  431.  
  432.